package v1

import (
	"net/http"
	"strconv"

	"zhihu-api/models"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// 创建问题请求
type CreateQuestionRequest struct {
	Title       string `json:"title" binding:"required,min=5,max=100"`
	Description string `json:"description"`
	Topics      []uint `json:"topics" binding:"required,min=1"`
}

// 创建问题
func CreateQuestion(c *gin.Context) {
	var req CreateQuestionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	userID := c.MustGet("userID").(uint)

	// 验证话题是否存在
	for _, topicID := range req.Topics {
		var topic models.Topic
		if err := models.DB.First(&topic, topicID).Error; err != nil {
			c.JSON(http.StatusBadRequest, gin.H{
				"error": "话题不存在: " + strconv.FormatUint(uint64(topicID), 10),
			})
			return
		}
	}

	// 创建问题
	question := models.Question{
		Title:        req.Title,
		Description:  req.Description,
		QuestionerID: userID,
	}

	tx := models.DB.Begin()
	if err := tx.Create(&question).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建问题失败"})
		return
	}

	// 关联话题
	for _, topicID := range req.Topics {
		questionTopic := models.QuestionTopic{
			QuestionID: question.ID,
			TopicID:    topicID,
		}
		if err := tx.Create(&questionTopic).Error; err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "关联话题失败"})
			return
		}
	}

	tx.Commit()

	// 返回创建的问题（包含关联话题）
	if err := models.DB.Preload("Topics").Preload("Questioner").First(&question, question.ID).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题详情失败"})
		return
	}

	c.JSON(http.StatusCreated, question)
}

// 获取问题列表
func ListQuestions(c *gin.Context) {
	var questions []models.Question
	page, _ := strconv.Atoi(c.DefaultQuery("page", "1"))
	limit, _ := strconv.Atoi(c.DefaultQuery("per_page", "10"))
	offset := (page - 1) * limit

	db := models.DB.Preload("Questioner").Preload("Topics")

	// 按话题筛选
	topicID := c.Query("topic")
	if topicID != "" {
		db = db.Joins("JOIN question_topics ON questions.id = question_topics.question_id").
			Where("question_topics.topic_id = ?", topicID)
	}

	if err := db.Order("created_at DESC").Limit(limit).Offset(offset).Find(&questions).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题列表失败"})
		return
	}

	c.JSON(http.StatusOK, questions)
}

// 获取问题详情
func GetQuestion(c *gin.Context) {
	id := c.Param("id")
	var question models.Question

	if err := models.DB.Preload("Questioner").Preload("Topics").First(&question, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	c.JSON(http.StatusOK, question)
}

// 更新问题请求
type UpdateQuestionRequest struct {
	Title       string `json:"title"`
	Description string `json:"description"`
	Topics      []uint `json:"topics"`
}

// 更新问题
func UpdateQuestion(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)

	var req UpdateQuestionRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 查找问题
	var question models.Question
	if err := models.DB.First(&question, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	// 检查权限
	if question.QuestionerID != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有权限更新此问题"})
		return
	}

	tx := models.DB.Begin()

	// 更新问题信息
	updates := make(map[string]interface{})
	if req.Title != "" {
		updates["title"] = req.Title
	}
	if req.Description != "" {
		updates["description"] = req.Description
	}

	if len(updates) > 0 {
		if err := tx.Model(&question).Updates(updates).Error; err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "更新问题失败"})
			return
		}
	}

	// 更新话题关联
	if req.Topics != nil && len(req.Topics) > 0 {
		// 验证话题是否存在
		for _, topicID := range req.Topics {
			var topic models.Topic
			if err := tx.First(&topic, topicID).Error; err != nil {
				tx.Rollback()
				c.JSON(http.StatusBadRequest, gin.H{
					"error": "话题不存在: " + strconv.FormatUint(uint64(topicID), 10),
				})
				return
			}
		}

		// 删除旧关联
		if err := tx.Where("question_id = ?", id).Delete(&models.QuestionTopic{}).Error; err != nil {
			tx.Rollback()
			c.JSON(http.StatusInternalServerError, gin.H{"error": "更新话题关联失败"})
			return
		}

		// 添加新关联
		for _, topicID := range req.Topics {
			questionTopic := models.QuestionTopic{
				QuestionID: question.ID,
				TopicID:    topicID,
			}
			if err := tx.Create(&questionTopic).Error; err != nil {
				tx.Rollback()
				c.JSON(http.StatusInternalServerError, gin.H{"error": "添加话题关联失败"})
				return
			}
		}
	}

	tx.Commit()

	// 返回更新后的问题
	if err := models.DB.Preload("Topics").Preload("Questioner").First(&question, id).Error; err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取更新后的问题失败"})
		return
	}

	c.JSON(http.StatusOK, question)
}

// 删除问题
func DeleteQuestion(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)

	// 查找问题
	var question models.Question
	if err := models.DB.First(&question, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	// 检查权限
	if question.QuestionerID != userID {
		c.JSON(http.StatusForbidden, gin.H{"error": "没有权限删除此问题"})
		return
	}

	tx := models.DB.Begin()

	// 删除话题关联
	if err := tx.Where("question_id = ?", id).Delete(&models.QuestionTopic{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除话题关联失败"})
		return
	}

	// 删除问题
	if err := tx.Delete(&question).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除问题失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "问题删除成功"})
}

// 关注问题
func FollowQuestion(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查问题是否存在
	var question models.Question
	if err := models.DB.First(&question, id).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			c.JSON(http.StatusNotFound, gin.H{"error": "问题不存在"})
			return
		}
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取问题失败"})
		return
	}

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowingQuestion{}).Where("user_id = ? AND question_id = ?", userID, idUint).Count(&count)
	if count > 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "已经关注该问题"})
		return
	}

	// 创建关注关系
	following := models.UserFollowingQuestion{
		UserID:     userID,
		QuestionID: uint(idUint),
	}

	tx := models.DB.Begin()
	if err := tx.Create(&following).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "关注问题失败"})
		return
	}

	// 更新问题的关注者数量
	if err := tx.Model(&models.Question{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count + ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新问题关注者数量失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "关注问题成功"})
}

// 取消关注问题
func UnfollowQuestion(c *gin.Context) {
	id := c.Param("id")
	userID := c.MustGet("userID").(uint)
	idUint, _ := strconv.ParseUint(id, 10, 32)

	// 检查是否已关注
	var count int64
	models.DB.Model(&models.UserFollowingQuestion{}).Where("user_id = ? AND question_id = ?", userID, idUint).Count(&count)
	if count == 0 {
		c.JSON(http.StatusBadRequest, gin.H{"error": "未关注该问题"})
		return
	}

	tx := models.DB.Begin()
	// 删除关注关系
	if err := tx.Where("user_id = ? AND question_id = ?", userID, idUint).Delete(&models.UserFollowingQuestion{}).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "取消关注问题失败"})
		return
	}

	// 更新问题的关注者数量
	if err := tx.Model(&models.Question{}).Where("id = ?", idUint).Update("follower_count", gorm.Expr("follower_count - ?", 1)).Error; err != nil {
		tx.Rollback()
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新问题关注者数量失败"})
		return
	}

	tx.Commit()
	c.JSON(http.StatusOK, gin.H{"message": "取消关注问题成功"})
}
